package com.tuzhi.sys.service.impl;

import com.tuzhi.base.jpa.domain.Pager;
import com.tuzhi.base.jpa.healper.QueryHelper;
import com.tuzhi.base.jpa.repository.BaseRepo;
import com.tuzhi.base.redis.MyRedisTemplate;
import com.tuzhi.base.service.impl.AbsBaseService;
import com.tuzhi.common.exception.BusinessException;
import com.tuzhi.sys.jpa.entity.SysRoleEntity;
import com.tuzhi.sys.jpa.entity.SysUserEntity;
import com.tuzhi.sys.jpa.repository.SysUserRepo;
import com.tuzhi.sys.service.SysRoleService;
import com.tuzhi.sys.service.SysUserRoleService;
import com.tuzhi.sys.service.SysUserService;
import com.tuzhi.utils.RsaEncipherUtil;
import org.apache.commons.lang3.StringUtils;
import org.mindrot.jbcrypt.BCrypt;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class SysUserServiceImpl extends AbsBaseService<SysUserEntity, Long> implements SysUserService {

    private static final Logger log = LoggerFactory.getLogger(SysUserServiceImpl.class);

    @Autowired
    MyRedisTemplate redisCache;

    @Autowired
    SysUserRepo repo;

    @Autowired
    SysRoleService roleService;

    @Autowired
    SysUserRoleService sysUserRoleService;

    @Autowired
    RsaEncipherUtil rsaEncipherUtil;
    @Override
    protected BaseRepo getThisRepo() {
        return repo;
    }

    @Override
    public SysUserEntity getUserByUserName(String userName) {
        return getOneUnique(SysUserEntity::getUsername, userName);
    }

    @Override
    public SysUserEntity getUserByMobile(String mobile) {
        return getOneUnique(SysUserEntity::getPhone,mobile);
    }

    @Override
    public List<SysRoleEntity> listRoles4UserName(String userName) {
        SysUserEntity sysUserEntity = findOne("username", userName);
        if (sysUserEntity == null) {
            return null;
        }
        List<Long> roleIds = sysUserRoleService.listRoleId4UserId(sysUserEntity.getId());
        List<SysRoleEntity> reles = new ArrayList<>(roleIds.size());
        roleIds.forEach(rid -> {
            SysRoleEntity roleEntity = roleService.get(rid);
            if (roleEntity != null) {
                reles.add(roleEntity);
            }
        });
        return reles;
    }

    @Value("${password.error-times}")
    private  String number;

    @Override
    public void modifyPwd(String oldPwd, String newPwd, String userName) {
        SysUserEntity sysUserEntity = getUserByUserName(userName);
        if (sysUserEntity == null) {
            throw new BusinessException("用户不存在：" + userName);
        }
        //解密密码
        Map<String, String> publicKeyAndPrivateKey = rsaEncipherUtil.getPublicKeyAndPrivateKey();
        String privateKeyStr = publicKeyAndPrivateKey.get(RsaEncipherUtil.PRIVATE_KEY_STR);
        String decryptOldPwd = RsaEncipherUtil.decryptByPrivateKey(oldPwd, privateKeyStr);
        String decryptNewPwd = RsaEncipherUtil.decryptByPrivateKey(newPwd, privateKeyStr);
        oldPwd=decryptOldPwd;
        newPwd=decryptNewPwd;

        boolean flag = BCrypt.checkpw(oldPwd, sysUserEntity.getPassword());

        if (!flag) {
            //TODO 后续加上修改错误的次数限制
            //错误次数存redis  key 为用户username 值为错误次数， 过期时间为24小时 ，错误次数大于等于5之后，修改过期时间为半小时
            Integer errorTimes = redisCache.getCacheObject("tz_sys_auth:password:error-times" + userName);
            if (errorTimes==null  ||  errorTimes.equals(0)){
                redisCache.set("tz_sys_auth:password:error-times" + userName,1,86400);
            }else {
                errorTimes++;
                Integer integer = Integer.valueOf(number);
                if (errorTimes>=integer ){
                    redisCache.set("tz_sys_auth:password:error-times" + userName,5,1800);
                    throw  new BusinessException("修改次数超过限制");
                }else {
                    redisCache.set("tz_sys_auth:password:error-times" + userName,errorTimes,86400);
                }
            }
            throw new BusinessException("原密码不对");
        }



        String newPwd_ = BCrypt.hashpw(newPwd, BCrypt.gensalt());
        sysUserEntity.setPassword(newPwd_);
        repo.save(sysUserEntity);
        log.info("修改密码成功：{}", userName);

    }

    @Override
    public void modifyPwd4Amin(String newPwd, String userName) {
        SysUserEntity sysUserEntity = getUserByUserName(userName);
        if (sysUserEntity == null) {
            throw new BusinessException("用户不存在：" + userName);
        }

        //解密密码
        Map<String, String> publicKeyAndPrivateKey = rsaEncipherUtil.getPublicKeyAndPrivateKey();
        String privateKeyStr = publicKeyAndPrivateKey.get(RsaEncipherUtil.PRIVATE_KEY_STR);
        String decryptNewPwd = RsaEncipherUtil.decryptByPrivateKey(newPwd, privateKeyStr);
        newPwd=decryptNewPwd;

        String newPwd_ = BCrypt.hashpw(newPwd, BCrypt.gensalt());
        sysUserEntity.setPassword(newPwd_);
        repo.save(sysUserEntity);
        log.info("修改密码成功：{}", userName);
    }


    @Override
    public SysUserEntity saveUserAndRole(SysUserEntity sysUserEntity) {
        if (sysUserEntity == null) {
            throw new BusinessException("提交内容不能为空");
        }
        if (sysUserEntity.getId() == null) {
            SysUserEntity entity = getOneUnique(SysUserEntity::getUsername, sysUserEntity.getUsername());
            if (entity != null) {
                throw new BusinessException(String.format("帐号己存在：%s", entity.getUsername()));
            }
            entity = getOneUnique(SysUserEntity::getNickname, sysUserEntity.getNickname());
            if (entity != null) {
                throw new BusinessException(String.format("Nickname己存在 不能重复：%s", entity.getUsername()));
            }
            if (StringUtils.isEmpty(sysUserEntity.getPassword())) {
                sysUserEntity.setPassword("123");
            }
            String newPwd_ = BCrypt.hashpw(sysUserEntity.getPassword(), BCrypt.gensalt());
            sysUserEntity.setPassword(newPwd_);
            SysUserEntity entity1 = repo.save(sysUserEntity);
            sysUserRoleService.saveUserRole(entity1.getId(), roleName2RoleIds(sysUserEntity.getRoles()));
            return entity1;
        } else {
            QueryHelper.Builder<SysUserEntity> builder = new QueryHelper.Builder<>();
            builder.neq(SysUserEntity::getUsername, sysUserEntity.getUsername());
            builder.eq(SysUserEntity::getNickname, sysUserEntity.getNickname());
            List<SysUserEntity> list = repo.findAll(builder.build().getWhereConditionBO());
            if (list != null && list.size() > 0) {
                throw new BusinessException(String.format("Nickname己存在 不能重复：%s", sysUserEntity.getUsername()));
            }
            SysUserEntity loadDbEntity = getOneUnique(SysUserEntity::getUsername, sysUserEntity.getUsername());
            if (StringUtils.isNotEmpty(sysUserEntity.getPassword())) {
                String newPwd_ = BCrypt.hashpw(sysUserEntity.getPassword(), BCrypt.gensalt());
                loadDbEntity.setPassword(newPwd_);
            }
            loadDbEntity.setNickname(sysUserEntity.getNickname());
            loadDbEntity.setOrgId(sysUserEntity.getOrgId());
            loadDbEntity.setPhone(sysUserEntity.getPhone());
            loadDbEntity.setEmail(sysUserEntity.getEmail());
            sysUserRoleService.saveUserRole(loadDbEntity.getId(), roleName2RoleIds(sysUserEntity.getRoles()));
            repo.save(loadDbEntity);
            return loadDbEntity;
        }
    }

    public Set<Long> roleName2RoleIds(Collection<String> roleName) {
        List<String> roleNames = new ArrayList<>();
        roleNames.addAll(roleName);
        List<SysRoleEntity> rs = roleService.getRoles(roleNames);
        Set<Long> roleIds = rs.stream()
                .map(SysRoleEntity::getId) // 提取每个 User 对象的 userId 字段
                .collect(Collectors.toSet()); // 将所有 userId 值收集到 Set 集合中
        return roleIds;
    }


    @Transactional(readOnly = true)
    @Override
    public Pager<SysUserEntity> listPager(Pager<SysUserEntity> pager) {
        Pager<SysUserEntity> pager1 = super.listPager(pager);
        List<SysUserEntity> datas = pager1.getData();
        if (datas != null && !datas.isEmpty()) {
            datas.forEach(item -> {
                /*List<SysRoleEntity> listRole = roleService.listUserRole(item.getId());
                if (listRole != null && !listRole.isEmpty()) {
                    Set<String> roleMap = new HashSet<>();
                    listRole.forEach(role -> {
                        roleMap.add(role.getName());
                    });
                    item.setRoles(roleMap);
                }*/
                item.setPassword(null);
                item.setSalt(null);
            });
        }
        return pager1;
    }

    @Override
    public void modifyStauts(Long userId, Integer sysStatus) {
        if (userId == null || userId.intValue() == 0) {
            throw new BusinessException("用户ID不能为空");
        }

        if (sysStatus == null) {
            throw new BusinessException("用户状态不能为空");
        }
        SysUserEntity entity = repo.getById(userId);

        if (entity == null) {
            throw new BusinessException("用户不存在：" + userId);
        }

        entity.setSysStatus(sysStatus);
        repo.save(entity);
    }
}
